<template>
  <div class="page-container">
    <head-component></head-component>
    <div class="main-container">
      <aside-component></aside-component>
      <div class="content-container">
        <el-card class="box-card">
          <template #header>
            <div class="card-header">
              <span>轮播图管理</span>
              <div class="search-inputs">
                <el-button type="success" @click="handleAdd">新增轮播图</el-button>
              </div>
            </div>
          </template>

          <el-table
            v-loading="loading"
            :data="banners.list"
            style="width: 95%; margin: 0 auto;"
            empty-text="暂无轮播图数据">
            <el-table-column label="轮播图" width="150">
              <template #default="scope">
                <div class="banner-preview">
                  <el-image
                    v-if="scope.row.imageLoaded"
                    style="width: 120px; height: 60px"
                    :src="scope.row.imageUrl"
                    :preview-src-list="scope.row.imageUrl ? [scope.row.imageUrl] : []"
                    :hide-on-click-modal="false"
                    :preview-teleported="true"
                    fit="cover"
                    class="preview-image"
                    @click="handlePreview(scope.row)">
                    <template #error>
                      <div class="image-error">
                        <el-icon><Picture /></el-icon>
                        <span>加载失败</span>
                      </div>
                    </template>
                  </el-image>
                  <span v-else class="loading-text">加载中...</span>
                </div>
              </template>
            </el-table-column>

            <el-table-column prop="statue" label="状态" width="100">
              <template #default="scope">
                <el-tag :type="scope.row.statue === 1 ? 'success' : 'info'">
                  {{ scope.row.statue === 1 ? '启用' : '禁用' }}
                </el-tag>
              </template>
            </el-table-column>

            <el-table-column prop="createTime" label="创建时间" width="160" />
            <el-table-column prop="updateTime" label="更新时间" width="160" />
            <el-table-column label="操作" width="200" align="center">
              <template #default="scope">
                <el-button
                  size="small"
                  type="primary"
                  @click="handleEdit(scope.row)">
                  编辑
                </el-button>
                <el-button
                  size="small"
                  type="danger"
                  @click="handleDelete(scope.row)">
                  删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>

          <div class="pagination-container">
            <el-pagination
              v-model:current-page="currentPage"
              v-model:page-size="pageSize"
              :page-sizes="[5, 10, 15, 20]"
              :total="banners.total"
              layout="total, sizes, prev, pager, next, jumper"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
            />
          </div>
        </el-card>
      </div>
    </div>
    <foot-component></foot-component>
  </div>

  <!-- 编辑/新增轮播图对话框 -->
  <el-dialog :title="dialogTitle" v-model="dialogVisible" width="500px">
    <el-form :model="currentBanner" :rules="editRules" ref="editBannerForm" label-width="100px">
      <el-form-item label="轮播图" prop="imgUrl">
        <div class="image-uploader" @click="triggerFileInput">
          <img v-if="currentBanner.imageUrl" :src="currentBanner.imageUrl" class="banner-image" alt="轮播图">
          <div v-else class="image-uploader-icon">
            <el-icon><Plus /></el-icon>
            <span class="upload-text">点击上传</span>
          </div>
          <div v-if="currentBanner.imageUrl" class="image-uploader-mask">
            <span class="upload-text">点击上传</span>
          </div>
          <input
            type="file"
            ref="fileInput"
            @change="handleImageChange"
            accept="image/jpeg,image/png"
            style="display: none"
          >
        </div>
        <div class="image-info">
          <p class="image-tip">支持 JPG、PNG 格式</p>
          <p class="image-tip">文件小于 2MB</p>
        </div>
      </el-form-item>

      <el-form-item label="状态" prop="statue">
        <el-select v-model="currentBanner.statue" placeholder="请选择状态">
          <el-option label="启用" :value="1"></el-option>
          <el-option label="禁用" :value="0"></el-option>
        </el-select>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitForm">保存</el-button>
      </span>
    </template>
  </el-dialog>

  <!-- 添加图片预览组件 -->
  <el-image-viewer
    v-if="previewVisible"
    :url-list="[previewUrl]"
    :initial-index="0"
    :hide-on-click-modal="false"
    :teleported="true"
    @close="previewVisible = false"
  />
</template>

<script>
import { ElMessage, ElMessageBox } from 'element-plus'
import AsideComponent from '../components/Aside.vue'
import HeadComponent from '../components/Head.vue'
import FootComponent from '../components/Foot.vue'
import { Plus, Picture } from '@element-plus/icons-vue'

export default {
  name: 'BannersManger',
  components: {
    AsideComponent,
    HeadComponent,
    FootComponent,
    Plus,
    Picture
  },

  data () {
    return {
      banners: {
        total: 0,
        list: [],
        pageSize: 5,
        pageNum: 1
      },
      loading: false,
      currentPage: 1,
      pageSize: 5,
      dialogVisible: false,
      dialogTitle: '',
      currentBanner: {
        file: null,
        statue: 1,
        imgUrl: '',
        imageUrl: ''
      },
      editRules: {
        imgUrl: [
          { required: true, message: '请上传轮播图', trigger: 'change' }
        ],
        statue: [
          { required: true, message: '请选择状态', trigger: 'change' }
        ]
      },
      previewVisible: false,
      previewUrl: ''
    }
  },

  mounted () {
    this.getBannerList()
  },

  methods: {
    // 获取轮播图列表
    async getBannerList () {
      this.loading = true
      try {
        const response = await this.$ajax.get('/admin/banners/selectAllBanners', {
          params: {
            pageNum: this.currentPage,
            pageSize: this.pageSize
          }
        })
        const resp = response.data
        if (resp.code === 0) {
          this.banners = { ...resp.data }
          this.currentPage = resp.data.pageNum
          this.pageSize = resp.data.pageSize

          // 为每个轮播图加载图片
          if (this.banners.list && this.banners.list.length > 0) {
            for (const banner of this.banners.list) {
              await this.loadBannerImage(banner)
            }
          }
        } else {
          ElMessage.error(resp.msg || '获取轮播图列表失败')
        }
      } catch (error) {
        console.error('获取轮播图列表失败:', error)
        ElMessage.error('获取轮播图列表失败')
      } finally {
        this.loading = false
      }
    },

    // 异步加载轮播图
    async loadBannerImage (banner) {
      banner.imageLoaded = false
      banner.imageUrl = ''

      const filename = banner.imgUrl
      if (!filename || filename.trim() === '') {
        banner.imageUrl = ''
        banner.imageLoaded = true
        return
      }

      try {
        const url = `/photo/view?filename=${encodeURIComponent(filename)}`
        const response = await this.$ajax.get(url, { responseType: 'blob' })
        const reader = new FileReader()
        reader.onloadend = () => {
          banner.imageUrl = reader.result
          banner.imageLoaded = true
        }
        reader.readAsDataURL(response.data)
      } catch (error) {
        console.error('加载轮播图失败:', error)
        banner.imageUrl = ''
        banner.imageLoaded = true
      }
    },

    // 处理分页
    handleSizeChange (val) {
      this.pageSize = val
      this.getBannerList()
    },

    handleCurrentChange (val) {
      this.currentPage = val
      this.getBannerList()
    },

    // 新增轮播图
    handleAdd () {
      this.dialogVisible = true
      this.dialogTitle = '新增轮播图'
      this.currentBanner = {
        file: null,
        statue: 1,
        imgUrl: '',
        imageUrl: ''
      }
      if (this.$refs.editBannerForm) {
        this.$refs.editBannerForm.resetFields()
      }
    },

    // 编辑轮播图
    async handleEdit (row) {
      this.dialogVisible = true
      this.dialogTitle = '编辑轮播图'
      // 保存原始图片URL，避免状态改变时重新加载
      const originalImageUrl = row.imageUrl
      const originalImageLoaded = row.imageLoaded

      this.currentBanner = {
        id: row.id,
        imgUrl: row.imgUrl,
        statue: Number(row.statue),
        imageUrl: originalImageUrl,
        imageLoaded: originalImageLoaded
      }

      // 只有在图片未加载时才重新加载
      if (!originalImageLoaded) {
        await this.loadBannerImage(this.currentBanner)
      }

      if (this.$refs.editBannerForm) {
        this.$refs.editBannerForm.resetFields()
      }
    },

    // 删除轮播图
    handleDelete (row) {
      ElMessageBox.confirm(
        '确定要删除这个轮播图吗？',
        '警告',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(() => {
        this.$ajax.delete(`/admin/banners/deleteBanner?bannerId=${encodeURIComponent(row.id)}`)
          .then(response => {
            const resp = response.data
            if (resp.code === 0) {
              ElMessage.success('轮播图删除成功')
              this.getBannerList()
            } else {
              ElMessage.error(resp.msg || '轮播图删除失败')
            }
          })
          .catch(error => {
            console.error('删除轮播图失败:', error)
            ElMessage.error('删除轮播图失败，请稍后重试')
          })
      }).catch(() => {
        ElMessage.info('已取消删除')
      })
    },

    // 触发文件选择
    triggerFileInput () {
      this.$refs.fileInput.click()
    },

    // 处理图片上传
    handleImageChange (event) {
      const fileInput = event.target
      if (!fileInput.files.length) return

      const file = fileInput.files[0]
      const isJPG = file.type === 'image/jpeg' || file.type === 'image/png'
      const isLt2M = file.size / 1024 / 1024 < 2

      if (!isJPG) {
        ElMessage.error('上传图片只能是 JPG/PNG 格式!')
        fileInput.value = ''
        return
      }
      if (!isLt2M) {
        ElMessage.error('上传图片大小不能超过 2MB!')
        fileInput.value = ''
        return
      }

      // 存储文件对象
      this.currentBanner.file = file
      // 本地预览
      const reader = new FileReader()
      reader.onloadend = () => {
        this.currentBanner.imageUrl = reader.result
      }
      reader.readAsDataURL(file)

      fileInput.value = ''
    },

    // 提交表单
    submitForm () {
      this.$refs.editBannerForm.validate(async (valid) => {
        if (valid) {
          try {
            // 构建提交数据
            const submitData = {
              id: this.currentBanner.id,
              statue: Number(this.currentBanner.statue),
              imgUrl: this.currentBanner.imgUrl // 如果是编辑且没有新图片，使用原有图片URL
            }

            // 如果是新增，不需要提交 id
            if (!this.currentBanner.id) {
              delete submitData.id
            }

            const url = this.currentBanner.id
              ? '/admin/banners/updateBanner'
              : '/admin/banners/addBanner'

            // 验证状态值
            if (submitData.statue !== 0 && submitData.statue !== 1) {
              ElMessage.error('状态值无效，只能是 0 或 1')
              return
            }

            // 先保存信息
            const response = await this.$ajax.post(url, submitData)
            if (response.data.code === 0) {
              // 信息保存成功后，如果有新选择的文件，再上传图片
              if (this.currentBanner.file) {
                const formData = new FormData()
                formData.append('photo', this.currentBanner.file)

                const uploadResponse = await this.$ajax.post('/photo/upload_photo', formData, {
                  headers: { 'Content-Type': 'multipart/form-data' }
                })

                if (uploadResponse.data.code === 0) {
                  // 更新轮播图信息中的图片URL
                  const updateImgUrl = {
                    id: response.data.data.id || this.currentBanner.id,
                    imgUrl: uploadResponse.data.data,
                    statue: submitData.statue
                  }
                  // 更新图片URL
                  await this.$ajax.post('/admin/banners/updateBanner', updateImgUrl)

                  ElMessage.success(this.currentBanner.id ? '更新成功' : '添加成功')
                  this.dialogVisible = false
                  await this.getBannerList()
                } else {
                  ElMessage.error(uploadResponse.data.msg || '图片上传失败')
                  // 如果图片上传失败，回滚信息更新
                  if (this.currentBanner.id) {
                    // 恢复原有图片URL
                    const rollbackData = {
                      id: this.currentBanner.id,
                      imgUrl: this.currentBanner.imgUrl,
                      statue: submitData.statue
                    }
                    await this.$ajax.post('/admin/banners/updateBanner', rollbackData)
                  } else {
                    // 如果是新增，删除已创建的记录
                    await this.$ajax.delete(`/admin/banners/deleteBanner?bannerId=${encodeURIComponent(response.data.data.id)}`)
                  }
                  return
                }
              } else {
                // 如果没有新图片，直接完成
                ElMessage.success(this.currentBanner.id ? '更新成功' : '添加成功')
                this.dialogVisible = false
                await this.getBannerList()
              }
            } else {
              ElMessage.error(response.data.msg || (this.currentBanner.id ? '更新失败' : '添加失败'))
            }
          } catch (error) {
            console.error(this.currentBanner.id ? '更新失败:' : '添加失败:', error)
            ElMessage.error(this.currentBanner.id ? '更新失败，请稍后重试' : '添加失败，请稍后重试')
          }
        }
      })
    },

    // 修改预览处理方法
    handlePreview (row) {
      if (row.imageUrl) {
        this.previewUrl = row.imageUrl
        this.previewVisible = true
      }
    }
  }
}
</script>

<style scoped>
.page-container {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.main-container {
  display: flex;
  flex: 1;
}

.content-container {
  flex: 1;
  padding: 0;
  background-color: #f5f7fa;
  height: 100%;
  width: 100%;
  overflow-y: auto;
}

.box-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  border: none;
  box-shadow: none;
}

.box-card :deep(.el-card__header) {
  padding: 0;
  border-bottom: none;
}

.box-card :deep(.el-card__body) {
  padding: 0;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  background-color: #fff;
  border-bottom: 1px solid #ebeef5;
  border-top: 1px solid #ebeef5;
}

.search-inputs {
  display: flex;
  align-items: center;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
  padding: 16px 20px;
  background-color: #fff;
  border-top: 1px solid #ebeef5;
}

/* 表格样式优化 */
:deep(.el-table) {
  border: none;
  background-color: #fff;
}

:deep(.el-table::before) {
  display: none;
}

:deep(.el-table__header) {
  /* background-color: #f5f7fa; */ /* 移除背景色 */
}

:deep(.el-table__header th) {
  /* background-color: #f5f7fa; */ /* 移除背景色 */
  border-bottom: 1px solid #ebeef5;
  color: #606266;
  font-weight: 600;
  height: 50px;
}

:deep(.el-table__row td) {
  border-bottom: 1px solid #ebeef5;
  padding: 12px 0;
}

:deep(.el-table__row:hover td) {
  background-color: #f5f7fa;
}

/* 轮播图预览样式 */
.banner-preview {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f5f7fa;
  border-radius: 4px;
  padding: 4px;
  min-height: 60px;
}

.banner-preview :deep(.el-image) {
  border-radius: 4px;
  overflow: hidden;
}

.banner-preview :deep(.el-image__inner) {
  transition: transform 0.3s ease;
}

.banner-preview :deep(.el-image__inner:hover) {
  transform: scale(1.05);
}

.banner-preview :deep(.el-image-viewer__wrapper) {
  background-color: rgba(0, 0, 0, 0.9);
}

.banner-preview :deep(.el-image-viewer__btn) {
  color: #fff;
}

.banner-preview :deep(.el-image-viewer__actions) {
  background-color: rgba(0, 0, 0, 0.7);
}

.loading-text {
  color: #909399;
  font-size: 14px;
}

.image-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #909399;
  font-size: 12px;
  height: 100%;
}

.image-error .el-icon {
  font-size: 24px;
  margin-bottom: 4px;
}

.image-uploader {
  display: inline-block;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: all 0.3s;
}

.image-uploader .banner-image {
  width: 200px;
  height: 100px;
  object-fit: cover;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  transition: all 0.3s;
}

.image-uploader-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s;
  border-radius: 4px;
}

.image-uploader:hover .image-uploader-mask {
  opacity: 1;
}

.image-uploader:hover .banner-image {
  border-color: #409eff;
  box-shadow: 0 0 8px rgba(64, 158, 255, 0.2);
}

.image-uploader-icon {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  color: #8c939d;
  width: 200px;
  height: 100px;
  border: 1px dashed #d9d9d9;
  border-radius: 4px;
  transition: all 0.3s;
}

.upload-text {
  margin-top: 8px;
  font-size: 14px;
  color: #fff;
}

.image-uploader:hover .image-uploader-icon {
  border-color: #409eff;
  color: #409eff;
}

.image-uploader:hover .upload-text {
  color: #409eff;
}

.image-uploader-mask .upload-text {
  color: #fff;
  margin-top: 0;
}

.image-info {
  margin-top: 10px;
  font-size: 12px;
  color: #606266;
}

.image-tip {
  line-height: 1.5;
  margin: 0;
}

/* 图片预览样式优化 */
.preview-image {
  cursor: pointer;
  position: relative;
}

.preview-image:hover::after {
  content: '查看图片';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  border-radius: 4px;
}

.image-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  border-radius: 4px;
}

:deep(.el-image-viewer__wrapper) {
  background-color: rgba(0, 0, 0, 0.9);
}

:deep(.el-image-viewer__btn) {
  color: #fff;
  font-size: 24px;
  opacity: 0.8;
}

:deep(.el-image-viewer__btn:hover) {
  opacity: 1;
}

:deep(.el-image-viewer__actions) {
  background-color: rgba(0, 0, 0, 0.7);
  border-radius: 4px;
}

:deep(.el-image-viewer__canvas) {
  transition: transform 0.3s ease;
}

:deep(.el-image-viewer__img) {
  max-width: 90vw;
  max-height: 90vh;
  object-fit: contain;
}

:deep(.el-image-viewer__close) {
  top: 20px;
  right: 20px;
}

:deep(.el-image-viewer__actions__inner) {
  padding: 12px 20px;
}

:deep(.el-image-viewer__actions__inner .el-icon) {
  font-size: 20px;
  margin: 0 8px;
}
</style>
